package net.sharpf2.api.world;

import java.util.ArrayList;
import net.sharpf2.sfcore.client.Npc;
import net.sharpf2.sfcore.client.NpcNode;
import net.sharpf2.api.Globals;
import net.sharpf2.api.Methods;
import net.sharpf2.api.types.Content;

/**
 *
 * @author Rick van Biljouw
 */
public class Entities {

    /**
     * Returns all of the NPCs in current region
     * @return ArrayList<Content<Npc>>
     */
    public static ArrayList<Content<Npc>> getNpcs() {
        ArrayList<Content<Npc>> npcs = new ArrayList<Content<Npc>>();
        for (NpcNode node : Globals.CLIENT.getNpcNodes()) {
            Npc npc = node.getNpc();
            if (npc != null && npc.getDef().getId() > 0) {
                npcs.add(new Content<Npc>(npc));
            }
        }

        return npcs;
    }

    /**
     * Returns the nearest npc matching one of specified ids in the current region
     * @param   ids NPC ids.
     * @return  Content<Npc>
     */
    public static Content<Npc> getNearestNpc(int... ids) {
        int curDist = 9999;
        Content<Npc> best = null;
        for (Content<Npc> npc : getNpcs()) {
            for (int id : ids) {
                if (npc.getContent().getDef().getId() == id) {
                    int tDist = 0;
                    if((tDist = (int) npc.getContent().getWorldPosition().distance(Methods.getMyPlayer().getContent().getWorldPosition())) < curDist) {
                        best = npc;
                        curDist = tDist;
                    }
                }
            }
        }
        return best;
    }

    /**
     * Returns the nearest npc matching one of specified ids in the current region
     * @param   ids NPC ids.
     * @return  Content<Npc>
     */
    public static Content<Npc> getNearestFreeNpc(int... ids) {
        int curDist = 9999;
        Content<Npc> best = null;
        for (Content<Npc> npc : getNpcs()) {
            for (int id : ids) {
                if (npc.getContent().getDef().getId() == id && npc.getContent().idle()) {
                    int tDist = 0;
                    if((tDist = (int) npc.getContent().getWorldPosition().distance(Methods.getMyPlayer().getContent().getWorldPosition())) < curDist) {
                        best = npc;
                        curDist = tDist;
                    }
                }
            }
        }
        return best;
    }
    
    /**
     * Returns the nearest npc matching one of specified ids in the current region
     * @param ids
     * @return 
     */
    public static Content<Npc> getNearestNpc(Area area, int... ids) {
        int curDist = 9999;
        Content<Npc> best = null;
        for (Content<Npc> npc : getNpcs()) {
            for (int id : ids) {
                if (npc.getContent().getDef().getId() == id && area.contains(npc.getContent().getWorldPosition())) {
                    int tDist = 0;
                    if((tDist = (int) npc.getContent().getWorldPosition().distance(Methods.getMyPlayer().getContent().getWorldPosition())) < curDist) {
                        best = npc;
                        curDist = tDist;
                    }
                }
            }
        }
        return best;
    }

    /**
     * Returns the nearest npc matching one of specified ids in the current region
     * @param ids
     * @return 
     */
    public static Content<Npc> getNearestFreeNpc(Area area, int... ids) {
        int curDist = 9999;
        Content<Npc> best = null;
        for (Content<Npc> npc : getNpcs()) {
            for (int id : ids) {
                if (npc.getContent().getDef().getId() == id && npc.getContent().idle() && area.contains(npc.getContent().getWorldPosition())) {
                    int tDist = 0;
                    if((tDist = (int) npc.getContent().getWorldPosition().distance(Methods.getMyPlayer().getContent().getWorldPosition())) < curDist) {
                        best = npc;
                        curDist = tDist;
                    }
                }
            }
        }
        return best;
    }    

    /**
     * Returns the nearest npc matching one of specified names in the current region
     * @param   ids NPC ids.
     * @return  Content<Npc>
     */
    public static Content<Npc> getNearestNpc(String... ids) {
        int curDist = 9999;
        Content<Npc> best = null;
        for (Content<Npc> npc : getNpcs()) {
            for (String id : ids) {
                if (npc.getContent().getDef().getName().equals(id)) {
                    int tDist = 0;
                    if((tDist = (int) npc.getContent().getWorldPosition().distance(Methods.getMyPlayer().getContent().getWorldPosition())) < curDist) {
                        best = npc;
                        curDist = tDist;
                    }
                }
            }
        }
        return best;
    }

    /**
     * Returns the nearest npc matching one of specified names in the current region
     * @param   ids NPC ids.
     * @return  Content<Npc>
     */
    public static Content<Npc> getNearestFreeNpc(String... ids) {
        int curDist = 9999;
        Content<Npc> best = null;
        for (Content<Npc> npc : getNpcs()) {
            for (String id : ids) {
                if (npc.getContent().getDef().getName().equals(id) && npc.getContent().idle()) {
                    int tDist = 0;
                    if((tDist = (int) npc.getContent().getWorldPosition().distance(Methods.getMyPlayer().getContent().getWorldPosition())) < curDist) {
                        best = npc;
                        curDist = tDist;
                    }
                }
            }
        }
        return best;
    }
}
